/*************************************************************************
	> File Name: port.c
	> Author: 
	> Mail: 
	> Created Time: 2018年11月06日 星期二 10时48分52秒
 ************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<termios.h>
#include<errno.h>
#include<string.h>
#include<time.h>
#include"../include/port.h"

int OpenUART(char *port)
{
    int fd = 0;
    fd = open(port,O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (FALSE == fd)
    {
        perror("can't open serial port");
        return FALSE;
    }
    return fd;
}

int SetUART(int fd,int speed,int flow_ctrl,int databits,int stopbits,int parity)
{
    struct termios options;
    if (tcgetattr(fd,&options) != 0)
    {
        perror("error!\r\n");
        return FALSE;
    }
    switch (speed)
    {
        case 115200:
            cfsetispeed(&options,B115200);
            cfsetospeed(&options,B115200);
            break;
        case 9600:
            cfsetispeed(&options,B9600);
            cfsetospeed(&options,B9600);
            break;
        default:
            break;
    }
    options.c_cflag |= CLOCAL;
    options.c_cflag |= CREAD;
    switch (flow_ctrl)
    {
        case 0:
            options.c_cflag &= ~CRTSCTS;
            break;
        case 1:
            options.c_cflag |= CRTSCTS;
            break;
        case 2:
            options.c_cflag |= IXON | IXOFF | IXANY;
            break;
    }
    options.c_cflag &= ~CSIZE;
    switch (databits)
    {
        case 5:
            options.c_cflag |= CS5;
            break;
        case 6:
            options.c_cflag |= CS6;
            break;
        case 7:
            options.c_cflag |= CS7;
            break;
        case 8:
            options.c_cflag |= CS8;
            break;
        default:
            fprintf(stderr,"unsupported data size\r\n");
            return FALSE;
    }
    switch (parity)
    {
        case 'n':
        case 'N':
            options.c_iflag |= IGNPAR;
            break;
        case 'o':
        case 'O':
            options.c_cflag |= (PARODD | PARENB);
            options.c_cflag |= INPCK;
            break;
        case 'e':
        case 'E':
            options.c_cflag |= PARENB;
            options.c_cflag &= ~PARODD;
            options.c_cflag |= INPCK;
            break;
        case 's':
        case 'S':
            options.c_cflag &= ~PARENB;
            options.c_cflag &= ~CSTOPB;
            break;
        default:
            fprintf(stderr,"unsupported parity\r\n");
            return FALSE;
    }
    switch (stopbits)
    {
        case 1:
            options.c_cflag &= ~CSTOPB;
            break;
        case 2:
            options.c_cflag |= CSTOPB;
            break;
        default:
            fprintf(stderr,"unsupported stop bits\r\n");
            return FALSE;
    }
    //options.c_cflag &= ~OPOST;
    options.c_oflag = 0;
    options.c_lflag = 0;
    if (tcsetattr(fd,TCSANOW,&options) != 0)
    {
        perror("set error!\r\n");
        return FALSE;
    }
    return TRUE;
}

int UARTRecv(int fd,char *rcvBuf,int dataLen)
{
    int len = 0;
    int fs = 0;
    fd_set fs_read;
    struct timeval time;
    FD_ZERO(&fs_read);
    FD_SET(fd,&fs_read);
    time.tv_sec = 10;
    time.tv_usec = 0;
    fs = select(fd + 1,&fs_read,NULL,NULL,&time);
    if (fs)
    {
        len = read(fd,rcvBuf,dataLen);
        return len;
    }
    else
    {
        return FALSE;
    }
}

int UARTSend(int fd,char *sendBuf,int dataLen)
{
    int ret = 0;
    ret = write(fd,sendBuf,dataLen);
    if (ret == dataLen)
    {
        printf("send ok!\r\n");
        return ret;
    }
    else
    {
        printf("send error!\r\n");
        tcflush(fd,TCOFLUSH);
        return FALSE;
    }
}

void UARTClose(int fd)
{
    close(fd);
}

int InitGPS(int fd)
{
    char *power = "AT+CGPSPWR=1\r\n";
    char *restoration = "AT+CGPSRST=1\r\n";
    UARTSend(fd,power,sizeof(power));
    UARTSend(fd,restoration,sizeof(restoration));
    return 0;
}
